package sli.sli2.pcp;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.bouncycastle.openssl.PEMReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sli.sli2.pcp.tcp.TCPConnectionHandler;

/**
 * Executable main class
 * @author Group 8, Khassraf Roman, Mueller Robin, Zischka Stefan
 *
 */
public class Provider {

	private static int port;
    private static final Logger log = LoggerFactory.getLogger(Provider.class);
    private static PrivateKey providerPrivateKey;
    
    private static String pathToPrivateKey;
    private static String pathToPubkeysFolder;
	
	public static void main(String[] args) {
		
		readProperties();
		
		readPrivateKey();
		
		listenForConnections();
		
	}

	
	private static void readPrivateKey() {
		
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());


		PEMReader in = null;
		
		try {
			in = new PEMReader(new FileReader(pathToPrivateKey));
			KeyPair keyPair = (KeyPair) in.readObject();
			providerPrivateKey = keyPair.getPrivate();
			
			
		} catch (FileNotFoundException e1) {
			System.out.println("Error: Keyfile not found");
			System.exit(1);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}


	private static void listenForConnections() {
		
		try {
			ServerSocket serverSocket = new ServerSocket(port);
            log.info("ServerSocket started on port {}", String.valueOf(port));
			
			ExecutorService executor = Executors.newCachedThreadPool();
			
			TCPConnectionHandler tch = new TCPConnectionHandler(serverSocket, executor, providerPrivateKey, pathToPubkeysFolder);
			
			executor.execute(tch);
			
		} catch (IOException | SecurityException | IllegalArgumentException e) {
			log.error("Failed to listen on port {}", String.valueOf(port), e);
		}		
	}

	/**
	 * Reads all necessary property files, this includes but is not limited to:
	 * 	Public Keys
	 * 	Properties (port, etc.)
	 */
	private static void readProperties() {
        ResourceBundle propertiesBundle = ResourceBundle.getBundle("pcp");
		try {
            log.info("Parsing port from psp.properties.");
            port = Integer.parseInt(propertiesBundle.getString("port"));
            pathToPrivateKey = propertiesBundle.getString("privkey.path");
            pathToPubkeysFolder = propertiesBundle.getString("pubkeys.path");
        } catch (Exception ex) {
            log.error("Failed to parse pcp.properties");
        }
	}
}
